import React, { memo, useEffect, useRef, useState } from 'react';
import { StarFilled } from '@ant-design/icons';
import PropTypes from 'prop-types';

import style from './AnimationStar.module.scss';

const AnimationStar = memo((props) => {
    const { starDom, updateStarDom } = props;
    const starRef = useRef();
    const [ animating, setAnimating ] = useState(null);

    useEffect(() => {
        if (!starDom || !starRef.current) {
            return;
        }
        
        // 收藏图标位置
        const starBound = starDom.getBoundingClientRect();
        const x1 = starBound.left;
        const y1 = -starBound.top;

        // 收藏文字位置
        const favoriteFolderBound = document.querySelector('#localPlots').getBoundingClientRect();
        const x2 = favoriteFolderBound.left + (favoriteFolderBound.right - favoriteFolderBound.left)/2 - starRef.current.offsetWidth/2;
        const y2 = -favoriteFolderBound.top;

        // 抛物线顶点(h,0)
        let h, a;

        if (x1 > x2 || x1 < x2) {
            h = (x2 * Math.sqrt(y1 / y2) + x1) / (Math.sqrt( y1 / y2) + 1);
            a = y1 / Math.pow((x1 - h), 2);
        } else {
            h = x1;
        }
        
        // 初始位置
        const animationStar = starRef.current;
        animationStar.style.left = x1 + 'px';
        animationStar.style.top = -y1 + 'px';

        let step = 0;

        if (h !== x1) {
            step = Math.abs(x2 - x1) / 1000 * (1000 / 90);
        } else {
            step = Math.abs(y1 - y2) / 1000 * (1000 / 90);
        }
        
        function starMove(left, top) {
            requestAnimationFrame(() => {
                let nextLeft, nextTop;

                if (x1 !== x2) {
                    nextLeft = x1 > x2 ? left - step : left + step;
                    nextTop = a * Math.pow((nextLeft - h), 2);
                } else {
                    nextLeft = x1;
                    nextTop = top + step;
                }
                 
                animationStar.style.left = nextLeft + 'px'; 
                animationStar.style.top = -nextTop + 'px';

                if ((x1 > x2 && nextLeft < x2)
                    || (x1 < x2 && nextLeft > x2)
                    || (x1 === x2 && nextTop > y2)) {
                        updateStarDom(null);
                        setAnimating(false);
                    return;
                }

                starMove(nextLeft, nextTop);
            });
        }
        
        if (!animating) {
            setAnimating(true);
            starMove(x1, y1);    
        }
    }, [starDom, updateStarDom, animating]);

    if (!starDom) {
        return null;
    }

    return (
        <div ref={ starRef } className={ style.animationStar }>
            <StarFilled className={ style.star }/>
        </div>
    );
});

AnimationStar.displayName = 'AnimationStar';

AnimationStar.propTypes = {
    starDom: PropTypes.object,
    updateStarDom: PropTypes.func
}

export default AnimationStar;